package com.wfh.utils;

import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.wfh.common.ErrorCode;
import com.wfh.exception.BusinessException;
import io.github.bonigarcia.wdm.WebDriverManager;
import jakarta.annotation.PreDestroy;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.io.File;
import java.time.Duration;
import java.util.UUID;

/**
 * @Title: WebScreenHotUtils
 * @Author wangfenghuan
 * @Package com.wfh.aigenerator.utils
 * @Date 2025/8/8 20:19
 * @description:
 */
@Slf4j
public class WebScreenHotUtils {
    // 1、第一步是初始化驱动，需要注意避免重复初始化驱动
    // 1、在静态代码块初始化驱动确保整个应用程序的生命周期仅仅初始化一次
    // 2、默认使用已经初始化好的驱动实例
    // 3、在项目停止之前正确销毁驱动，释放资源

    private static final WebDriver webDriver;
    static {
        final int DEFAULT_HEIGHT = 900;
        final int DEFAULT_WIDTH = 1600;
        webDriver = initChromeDriver(DEFAULT_WIDTH, DEFAULT_HEIGHT);
    }

    /**
     * 初始化 Chrome 浏览器驱动
     */
    private static WebDriver initChromeDriver(int width, int height) {
        try {
            // 自动管理 ChromeDriver
            WebDriverManager.chromedriver().setup();
            // 配置 Chrome 选项
            ChromeOptions options = new ChromeOptions();
            // 无头模式
            options.addArguments("--headless");
            // 禁用GPU（在某些环境下避免问题）
            options.addArguments("--disable-gpu");
            // 禁用沙盒模式（Docker环境需要）
            options.addArguments("--no-sandbox");
            // 禁用开发者shm使用
            options.addArguments("--disable-dev-shm-usage");
            // 设置窗口大小
            options.addArguments(String.format("--window-size=%d,%d", width, height));
            // 禁用扩展
            options.addArguments("--disable-extensions");
            // 设置用户代理
            options.addArguments("--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36");
            // 创建驱动
            WebDriver driver = new ChromeDriver(options);
            // 设置页面加载超时
            driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(30));
            // 设置隐式等待
            driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
            return driver;
        } catch (Exception e) {
            log.error("初始化 Chrome 浏览器失败", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "初始化 Chrome 浏览器失败");
        }
    }

    @PreDestroy
    public static void destroy() {
        webDriver.quit();
    }

    /**
     * 保存图片到文件中去
     * @param imageBytes
     * @param filePath
     */
    private static void saveImage(byte[] imageBytes, String filePath) {
        try {
            FileUtil.writeBytes(imageBytes, filePath);
        } catch (IORuntimeException e) {
            log.error("保存截图失败", e);
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "保存截图失败");
        }
    }

    /**
     * 压缩图片
     * @param originFilePath
     * @param targetFilePath
     */
    private static void compressImage(String originFilePath, String targetFilePath) {
       // 设置图片压缩质量
        final float quality = 0.5f;
        try {
            ImgUtil.compress(
                    FileUtil.file(originFilePath),
                    FileUtil.file(targetFilePath),
                    quality
            );
        } catch (IORuntimeException e) {
            log.error("压缩图片失败", e);
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "压缩图片失败");
        }
    }

    private static void waitForPageLoad(WebDriver driver) {
        try {
            // 等待页面加载对象
            WebDriverWait webDriverWait = new WebDriverWait(driver, Duration.ofSeconds(10));
            // 等待网页读取完成
            webDriverWait.until(driver1 -> ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete"));
            // 额外等待一段时间，确保动态内容加载完成
            Thread.sleep(2000);
            log.info("页面中加载完成");
        } catch (InterruptedException e) {
            log.error("等待页面加载失败", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "等待页面加载失败");
        }
    }
    public static String takeScreenshot(String url) {
        if (StrUtil.isBlank(url)) {
            log.error("截图失败，url为空");
            return null;
        }
        try {
            // 创建临时目录
            String rootPath = System.getProperty("user.dir") + File.separator + "tmp" + File.separator + "screenshot"
                    +File.separator + UUID.randomUUID().toString().substring(0, 8);
            FileUtil.mkdir(rootPath);
            // 图片后缀
            final String IMAGE_SUFFIX = ".png";
            // 原始的截图文件路径
            String imageSavePath = rootPath + File.separator + RandomUtil.randomNumbers(5) + IMAGE_SUFFIX;
            // 访问网页
            webDriver.get(url);
            // 等待页面加载完成
            waitForPageLoad(webDriver);
            // 截图
            byte[] screenshot = ((TakesScreenshot) webDriver).getScreenshotAs(OutputType.BYTES);
            // 保存原始图片
            saveImage(screenshot, imageSavePath);
            // 压缩图片
            final String compressedImageSavePath = rootPath + File.separator + RandomUtil.randomNumbers(5) + IMAGE_SUFFIX;
            compressImage(imageSavePath, compressedImageSavePath);
            log.info("截图成功，保存路径为：{}", compressedImageSavePath);
            // 删除原始图片，保存压缩图片
            FileUtil.del(imageSavePath);
            return compressedImageSavePath;
        } catch (Exception e) {
            log.error("截图失败", e);
            return null;
        }
    }

}
